--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Node / ReticulumProjects / MeshChatX.git / files / meshchatx / src / backend / diagnostics / memory_diagnostics.py
Displaying Raw • Download
meshchatx/src/backend/diagnostics/memory_diagnostics.py fa34a0731c96da043235b215b6497e9138d3352f (fa34a073) Text, 19.89 KB
Tff7b72import T7ee787collections
Tff7b72import T7ee787gc
Tff7b72import T7ee787sys
Tff7b72import T7ee787tracemalloc
Tff7b72from T7ee787typing Tff7b72import Te6edf3Any
Tff7b72def Td2a8ff_obj_sizeTb4b4b4(Te6edf3objTb4b4b4: Te6edf3AnyTb4b4b4) Tff7b72-Tff7b72> Tffa657intTb4b4b4:
Tff7b72tryTb4b4b4:
Tff7b72return Te6edf3sysTff7b72.Td2a8ffgetsizeofTb4b4b4(Te6edf3objTb4b4b4)
Tff7b72except Tf85149ExceptionTb4b4b4:
Tff7b72return T79c0ff0
Tff7b72def Td2a8ff_safe_type_nameTb4b4b4(Te6edf3objTb4b4b4: Te6edf3AnyTb4b4b4) Tff7b72-Tff7b72> Tffa657strTb4b4b4:
Tff7b72tryTb4b4b4:
Tff7b72return Tffa657typeTb4b4b4(Te6edf3objTb4b4b4)Tff7b72.Td2a8ff__qualname__
Tff7b72except Tf85149ExceptionTb4b4b4:
Tff7b72return Ta5d6ff"Ta5d6ff<unknown>Ta5d6ff"
Tff7b72def Td2a8ff_safe_moduleTb4b4b4(Te6edf3objTb4b4b4: Te6edf3AnyTb4b4b4) Tff7b72-Tff7b72> Tffa657strTb4b4b4:
Tff7b72tryTb4b4b4:
Tff7b72return Tffa657typeTb4b4b4(Te6edf3objTb4b4b4)Tff7b72.Td2a8ff__module__
Tff7b72except Tf85149ExceptionTb4b4b4:
Tff7b72return Ta5d6ff"Ta5d6ff"
Tff7b72def Td2a8ff_is_reticulum_objTb4b4b4(Te6edf3objTb4b4b4: Te6edf3AnyTb4b4b4) Tff7b72-Tff7b72> Tffa657boolTb4b4b4:
Te6edf3mod Tff7b72= Te6edf3_safe_moduleTb4b4b4(Te6edf3objTb4b4b4)
Tff7b72return Ta5d6ff"Ta5d6ffRNSTa5d6ff" Tff7b72in Te6edf3mod Tff7b72or Ta5d6ff"Ta5d6ffLXMFTa5d6ff" Tff7b72in Te6edf3mod Tff7b72or Ta5d6ff"Ta5d6ffLXSTTa5d6ff" Tff7b72in Te6edf3mod Tff7b72or Ta5d6ff"Ta5d6ffmeshchatxTa5d6ff" Tff7b72in Te6edf3mod
Tff7b72def Td2a8ff_is_closureTb4b4b4(Te6edf3objTb4b4b4: Te6edf3AnyTb4b4b4) Tff7b72-Tff7b72> Tffa657boolTb4b4b4:
Tff7b72return Tffa657typeTb4b4b4(Te6edf3objTb4b4b4)Tff7b72.Td2a8ff__name__ Tff7b72in Tb4b4b4(Ta5d6ff"Ta5d6fffunctionTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ffcellTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ffcodeTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ffFrameTypeTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ffMethodTypeTa5d6ff"Tb4b4b4)
Tff7b72def Td2a8ff_classifyTb4b4b4(Te6edf3objTb4b4b4: Te6edf3AnyTb4b4b4) Tff7b72-Tff7b72> Tffa657strTb4b4b4:
Te6edf3t Tff7b72= Tffa657typeTb4b4b4(Te6edf3objTb4b4b4)
Tff7b72if Te6edf3t Tff7b72in Tb4b4b4(Tffa657strTb4b4b4, Tffa657bytesTb4b4b4, Tffa657bytearrayTb4b4b4, Tffa657intTb4b4b4, Tffa657floatTb4b4b4, Tffa657boolTb4b4b4, Tffa657typeTb4b4b4(Tff7b72NoneTb4b4b4)Tb4b4b4)Tb4b4b4:
Tff7b72return Ta5d6ff"Ta5d6ffbuiltinTa5d6ff"
Tff7b72if Tffa657isinstanceTb4b4b4(Te6edf3objTb4b4b4, Tb4b4b4(Tffa657listTb4b4b4, Tffa657tupleTb4b4b4, Tffa657setTb4b4b4, Tffa657frozensetTb4b4b4)Tb4b4b4)Tb4b4b4:
Tff7b72return Ta5d6ff"Ta5d6ffcontainerTa5d6ff"
Tff7b72if Tffa657isinstanceTb4b4b4(Te6edf3objTb4b4b4, Tffa657dictTb4b4b4)Tb4b4b4:
Tff7b72return Ta5d6ff"Ta5d6ffdictTa5d6ff"
Te6edf3mod Tff7b72= Te6edf3_safe_moduleTb4b4b4(Te6edf3objTb4b4b4)
Tff7b72if Ta5d6ff"Ta5d6ffRNSTa5d6ff" Tff7b72in Te6edf3modTb4b4b4:
Tff7b72return Ta5d6ff"Ta5d6ffRNSTa5d6ff"
Tff7b72if Ta5d6ff"Ta5d6ffLXMFTa5d6ff" Tff7b72in Te6edf3modTb4b4b4:
Tff7b72return Ta5d6ff"Ta5d6ffLXMFTa5d6ff"
Tff7b72if Ta5d6ff"Ta5d6ffLXSTTa5d6ff" Tff7b72in Te6edf3modTb4b4b4:
Tff7b72return Ta5d6ff"Ta5d6ffLXSTTa5d6ff"
Tff7b72if Ta5d6ff"Ta5d6ffmeshchatxTa5d6ff" Tff7b72in Te6edf3modTb4b4b4:
Tff7b72return Ta5d6ff"Ta5d6ffmeshchatxTa5d6ff"
Tff7b72if Te6edf3modTff7b72.Td2a8ffstartswithTb4b4b4(Tb4b4b4(Ta5d6ff"Ta5d6ffasyncioTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ffconcurrentTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ffthreadingTa5d6ff"Tb4b4b4)Tb4b4b4)Tb4b4b4:
Tff7b72return Ta5d6ff"Ta5d6ffasyncTa5d6ff"
Tff7b72return Ta5d6ff"Ta5d6ffotherTa5d6ff"
Tff7b72class T56d364_ObjectTypeTrackerTb4b4b4:
T8b949e"""Tracks per-type object counts across snapshots to detect accumulation.
History is bounded so that long-running processes do not accumulate an
ever-growing list of per-type count dictionaries. The very first
snapshot is retained separately so growth-since-start remains accurate
even after older readings are evicted.
"""
Tff7b72def Tff7b72__init__Tb4b4b4(Tff7b72selfTb4b4b4, Te6edf3max_historyTb4b4b4: Tffa657int Tff7b72= T79c0ff64Tb4b4b4) Tff7b72-Tff7b72> Tff7b72NoneTb4b4b4:
Tff7b72selfTff7b72.Td2a8ff_max_history Tff7b72= Tffa657maxTb4b4b4(T79c0ff3Tb4b4b4, Te6edf3max_historyTb4b4b4)
Tff7b72selfTff7b72.Td2a8ff_historyTb4b4b4: Te6edf3collectionsTff7b72.Td2a8ffdequeTb4b4b4[Tffa657dictTb4b4b4[Tffa657strTb4b4b4, Tffa657intTb4b4b4]Tb4b4b4] Tff7b72= Te6edf3collectionsTff7b72.Td2a8ffdequeTb4b4b4(
Te6edf3maxlenTff7b72=Tff7b72selfTff7b72.Td2a8ff_max_historyTb4b4b4,
Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ff_firstTb4b4b4: Tffa657dictTb4b4b4[Tffa657strTb4b4b4, Tffa657intTb4b4b4] Tff7b72= Tb4b4b4{Tb4b4b4}
Tff7b72selfTff7b72.Td2a8ff_last_fullTb4b4b4: Tffa657dictTb4b4b4[Tffa657strTb4b4b4, Tffa657intTb4b4b4] Tff7b72= Tb4b4b4{Tb4b4b4}
Tff7b72def Td2a8ffrecordTb4b4b4(Tff7b72selfTb4b4b4) Tff7b72-Tff7b72> Tff7b72NoneTb4b4b4:
Te6edf3countsTb4b4b4: Tffa657dictTb4b4b4[Tffa657strTb4b4b4, Tffa657intTb4b4b4] Tff7b72= Tb4b4b4{Tb4b4b4}
Tff7b72tryTb4b4b4:
Tff7b72for Te6edf3obj Tff7b72in Te6edf3gcTff7b72.Td2a8ffget_objectsTb4b4b4(Tb4b4b4)Tb4b4b4:
Tff7b72tryTb4b4b4:
Te6edf3name Tff7b72= Te6edf3_safe_type_nameTb4b4b4(Te6edf3objTb4b4b4)
Te6edf3countsTb4b4b4[Te6edf3nameTb4b4b4] Tff7b72= Te6edf3countsTff7b72.Td2a8ffgetTb4b4b4(Te6edf3nameTb4b4b4, T79c0ff0Tb4b4b4) Tff7b72+ T79c0ff1
Tff7b72except Tf85149ExceptionTb4b4b4:
Tff7b72continue
Tff7b72except Tf85149ExceptionTb4b4b4:
Tff7b72return
Tff7b72if Tff7b72not Tff7b72selfTff7b72.Td2a8ff_firstTb4b4b4:
Tff7b72selfTff7b72.Td2a8ff_first Tff7b72= Te6edf3counts
Tff7b72selfTff7b72.Td2a8ff_historyTff7b72.Td2a8ffappendTb4b4b4(Te6edf3countsTb4b4b4)
Tff7b72selfTff7b72.Td2a8ff_last_full Tff7b72= Te6edf3counts
Tf0883e@property
Tff7b72def Td2a8ffgrowth_since_firstTb4b4b4(Tff7b72selfTb4b4b4) Tff7b72-Tff7b72> Tffa657listTb4b4b4[Tffa657tupleTb4b4b4[Tffa657strTb4b4b4, Tffa657intTb4b4b4]Tb4b4b4]Tb4b4b4:
Tff7b72if Tff7b72not Tff7b72selfTff7b72.Td2a8ff_first Tff7b72or Tff7b72not Tff7b72selfTff7b72.Td2a8ff_historyTb4b4b4:
Tff7b72return Tb4b4b4[Tb4b4b4]
Te6edf3first Tff7b72= Tff7b72selfTff7b72.Td2a8ff_first
Te6edf3last Tff7b72= Tff7b72selfTff7b72.Td2a8ff_historyTb4b4b4[Tff7b72-T79c0ff1Tb4b4b4]
Te6edf3resultTb4b4b4: Tffa657listTb4b4b4[Tffa657tupleTb4b4b4[Tffa657strTb4b4b4, Tffa657intTb4b4b4]Tb4b4b4] Tff7b72= Tb4b4b4[Tb4b4b4]
Tff7b72for Te6edf3tnameTb4b4b4, Te6edf3count Tff7b72in Te6edf3lastTff7b72.Td2a8ffitemsTb4b4b4(Tb4b4b4)Tb4b4b4:
Te6edf3diff Tff7b72= Te6edf3count Tff7b72- Te6edf3firstTff7b72.Td2a8ffgetTb4b4b4(Te6edf3tnameTb4b4b4, T79c0ff0Tb4b4b4)
Tff7b72if Te6edf3diff Tff7b72> T79c0ff0Tb4b4b4:
Te6edf3resultTff7b72.Td2a8ffappendTb4b4b4(Tb4b4b4(Te6edf3tnameTb4b4b4, Te6edf3diffTb4b4b4)Tb4b4b4)
Te6edf3resultTff7b72.Td2a8ffsortTb4b4b4(Te6edf3keyTff7b72=Tff7b72lambda Te6edf3xTb4b4b4: Tff7b72-Te6edf3xTb4b4b4[T79c0ff1Tb4b4b4]Tb4b4b4)
Tff7b72return Te6edf3result
Tf0883e@property
Tff7b72def Td2a8ffaccumulating_typesTb4b4b4(Tff7b72selfTb4b4b4) Tff7b72-Tff7b72> Tffa657listTb4b4b4[Tffa657tupleTb4b4b4[Tffa657strTb4b4b4, Tffa657intTb4b4b4]Tb4b4b4]Tb4b4b4:
Tff7b72if Tffa657lenTb4b4b4(Tff7b72selfTff7b72.Td2a8ff_historyTb4b4b4) Tff7b72< T79c0ff3Tb4b4b4:
Tff7b72return Tb4b4b4[Tb4b4b4]
Te6edf3resultTb4b4b4: Tffa657listTb4b4b4[Tffa657tupleTb4b4b4[Tffa657strTb4b4b4, Tffa657intTb4b4b4]Tb4b4b4] Tff7b72= Tb4b4b4[Tb4b4b4]
Tff7b72for Te6edf3tname Tff7b72in Tff7b72selfTff7b72.Td2a8ff_historyTb4b4b4[Tff7b72-T79c0ff1Tb4b4b4]Tb4b4b4:
Te6edf3counts Tff7b72= Tb4b4b4[Te6edf3hTff7b72.Td2a8ffgetTb4b4b4(Te6edf3tnameTb4b4b4, T79c0ff0Tb4b4b4) Tff7b72for Te6edf3h Tff7b72in Tff7b72selfTff7b72.Td2a8ff_historyTb4b4b4]
Tff7b72if Tb4b4b4(
Tffa657allTb4b4b4(Te6edf3countsTb4b4b4[Te6edf3iTb4b4b4] Tff7b72<Tff7b72= Te6edf3countsTb4b4b4[Te6edf3i Tff7b72+ T79c0ff1Tb4b4b4] Tff7b72for Te6edf3i Tff7b72in Tffa657rangeTb4b4b4(Tffa657lenTb4b4b4(Te6edf3countsTb4b4b4) Tff7b72- T79c0ff1Tb4b4b4)Tb4b4b4)
Tff7b72and Te6edf3countsTb4b4b4[Tff7b72-T79c0ff1Tb4b4b4] Tff7b72- Te6edf3countsTb4b4b4[T79c0ff0Tb4b4b4] Tff7b72> T79c0ff0
Tb4b4b4)Tb4b4b4:
Te6edf3resultTff7b72.Td2a8ffappendTb4b4b4(Tb4b4b4(Te6edf3tnameTb4b4b4, Te6edf3countsTb4b4b4[Tff7b72-T79c0ff1Tb4b4b4] Tff7b72- Te6edf3countsTb4b4b4[T79c0ff0Tb4b4b4]Tb4b4b4)Tb4b4b4)
Te6edf3resultTff7b72.Td2a8ffsortTb4b4b4(Te6edf3keyTff7b72=Tff7b72lambda Te6edf3xTb4b4b4: Tff7b72-Te6edf3xTb4b4b4[T79c0ff1Tb4b4b4]Tb4b4b4)
Tff7b72return Te6edf3result
Tff7b72class T56d364MemoryDiagnosticsTb4b4b4:
T8b949e"""tracemalloc-based memory diagnostics for identifying leaks.
Python 3.14+ uses an incremental GC that spreads collection work across
allocations instead of doing one big sweep. Cyclic garbage can therefore
linger longer between full collections. This class helps detect
accumulating objects by:
* Taking periodic tracemalloc snapshots and diffing against a baseline.
* Tracking GC generation sizes (gen0/gen1/gen2 object counts).
* Profiling gc.get_objects() by type to spot monotonic growth.
* Finding the top-N allocation sites (filename + line number) that
contribute the most to memory growth.
Usage::
from meshchatx.src.backend.diagnostics import MemoryDiagnostics
diag = MemoryDiagnostics()
diag.start()
# ... let app run for a while ...
report = diag.report()
diag.stop()
All methods are safe to call when tracing is inactive (they return
empty/default values).
"""
Tff7b72def Tff7b72__init__Tb4b4b4(Tff7b72selfTb4b4b4, Te6edf3nframesTb4b4b4: Tffa657int Tff7b72= T79c0ff25Tb4b4b4, Te6edf3max_snapshotsTb4b4b4: Tffa657int Tff7b72= T79c0ff48Tb4b4b4) Tff7b72-Tff7b72> Tff7b72NoneTb4b4b4:
Tff7b72selfTff7b72.Td2a8ff_nframes Tff7b72= Te6edf3nframes
Tff7b72selfTff7b72.Td2a8ff_max_snapshots Tff7b72= Tffa657maxTb4b4b4(T79c0ff2Tb4b4b4, Te6edf3max_snapshotsTb4b4b4)
Tff7b72selfTff7b72.Td2a8ff_enabled Tff7b72= Tff7b72False
Tff7b72selfTff7b72.Td2a8ff_baselineTb4b4b4: Te6edf3tracemallocTff7b72.Td2a8ffSnapshot Tff7b72| Tff7b72None Tff7b72= Tff7b72None
Tff7b72selfTff7b72.Td2a8ff_snapshotsTb4b4b4: Tffa657listTb4b4b4[Te6edf3tracemallocTff7b72.Td2a8ffSnapshotTb4b4b4] Tff7b72= Tb4b4b4[Tb4b4b4]
Tff7b72selfTff7b72.Td2a8ff_gc_statsTb4b4b4: Tffa657listTb4b4b4[Tffa657dictTb4b4b4[Tffa657strTb4b4b4, Te6edf3AnyTb4b4b4]Tb4b4b4] Tff7b72= Tb4b4b4[Tb4b4b4]
Tff7b72selfTff7b72.Td2a8ff_total_snapshots Tff7b72= T79c0ff0
Tff7b72selfTff7b72.Td2a8ff_type_tracker Tff7b72= Te6edf3_ObjectTypeTrackerTb4b4b4(Te6edf3max_historyTff7b72=Te6edf3max_snapshotsTb4b4b4)
T8b949e# ------------------------------------------------------------------
T8b949e# Lifecycle
T8b949e# ------------------------------------------------------------------
Tff7b72def Td2a8ffstartTb4b4b4(Tff7b72selfTb4b4b4) Tff7b72-Tff7b72> Tff7b72NoneTb4b4b4:
Tff7b72if Tff7b72selfTff7b72.Td2a8ff_enabledTb4b4b4:
Tff7b72return
Tff7b72if Tff7b72not Te6edf3tracemallocTff7b72.Td2a8ffis_tracingTb4b4b4(Tb4b4b4)Tb4b4b4:
Te6edf3tracemallocTff7b72.Td2a8ffstartTb4b4b4(Tff7b72selfTff7b72.Td2a8ff_nframesTb4b4b4)
Tff7b72selfTff7b72.Td2a8ff_enabled Tff7b72= Tff7b72True
Tff7b72selfTff7b72.Td2a8ff_baseline Tff7b72= Te6edf3tracemallocTff7b72.Td2a8fftake_snapshotTb4b4b4(Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ff_snapshots Tff7b72= Tb4b4b4[Tff7b72selfTff7b72.Td2a8ff_baselineTb4b4b4]
Tff7b72selfTff7b72.Td2a8ff_total_snapshots Tff7b72= T79c0ff1
Tff7b72selfTff7b72.Td2a8ff_record_gc_statsTb4b4b4(Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ff_type_trackerTff7b72.Td2a8ffrecordTb4b4b4(Tb4b4b4)
Tffa657printTb4b4b4(
Ta5d6fffTa5d6ff"Ta5d6ff[mem_diag] Started tracing (nframes=Tffd700{Tff7b72selfTff7b72.Td2a8ff_nframesTffd700}Ta5d6ff, Ta5d6ff"
Ta5d6fffTa5d6ff"Ta5d6ffgc.freeze=Tffd700{Tffa657getattrTb4b4b4(Te6edf3gcTb4b4b4, Ta5d6ff'Ta5d6fffreeze_countTa5d6ff'Tb4b4b4, T79c0ff0Tb4b4b4)Tffd700}Ta5d6ff)Ta5d6ff"Tb4b4b4,
Tb4b4b4)
Tff7b72def Td2a8ffstopTb4b4b4(Tff7b72selfTb4b4b4) Tff7b72-Tff7b72> Tff7b72NoneTb4b4b4:
Tff7b72if Tff7b72not Tff7b72selfTff7b72.Td2a8ff_enabledTb4b4b4:
Tff7b72return
Tff7b72if Te6edf3tracemallocTff7b72.Td2a8ffis_tracingTb4b4b4(Tb4b4b4)Tb4b4b4:
Te6edf3tracemallocTff7b72.Td2a8ffstopTb4b4b4(Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ff_enabled Tff7b72= Tff7b72False
Tffa657printTb4b4b4(Ta5d6ff"Ta5d6ff[mem_diag] Stopped tracingTa5d6ff"Tb4b4b4)
Tff7b72def Td2a8ffresetTb4b4b4(Tff7b72selfTb4b4b4) Tff7b72-Tff7b72> Tff7b72NoneTb4b4b4:
Tff7b72selfTff7b72.Td2a8ffstopTb4b4b4(Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ff_baseline Tff7b72= Tff7b72None
Tff7b72selfTff7b72.Td2a8ff_snapshotsTff7b72.Td2a8ffclearTb4b4b4(Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ff_gc_statsTff7b72.Td2a8ffclearTb4b4b4(Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ff_total_snapshots Tff7b72= T79c0ff0
Tff7b72selfTff7b72.Td2a8ff_type_tracker Tff7b72= Te6edf3_ObjectTypeTrackerTb4b4b4(Te6edf3max_historyTff7b72=Tff7b72selfTff7b72.Td2a8ff_max_snapshotsTb4b4b4)
Tf0883e@property
Tff7b72def Td2a8ffenabledTb4b4b4(Tff7b72selfTb4b4b4) Tff7b72-Tff7b72> Tffa657boolTb4b4b4:
Tff7b72return Tff7b72selfTff7b72.Td2a8ff_enabled Tff7b72and Te6edf3tracemallocTff7b72.Td2a8ffis_tracingTb4b4b4(Tb4b4b4)
Tf0883e@property
Tff7b72def Td2a8fftotal_snapshotsTb4b4b4(Tff7b72selfTb4b4b4) Tff7b72-Tff7b72> Tffa657intTb4b4b4:
T8b949e"""Monotonic count of snapshots taken, independent of retention trimming."""
Tff7b72return Tff7b72selfTff7b72.Td2a8ff_total_snapshots
Tff7b72def Td2a8ff_trim_historyTb4b4b4(Tff7b72selfTb4b4b4) Tff7b72-Tff7b72> Tff7b72NoneTb4b4b4:
T8b949e"""Bound retained snapshots and GC records while preserving the baseline.
The baseline (index 0) is always kept so diff_snapshots and
gc_stats deltas remain anchored to application start; only the
intermediate readings are evicted once the cap is exceeded.
"""
Tff7b72if Tffa657lenTb4b4b4(Tff7b72selfTff7b72.Td2a8ff_snapshotsTb4b4b4) Tff7b72> Tff7b72selfTff7b72.Td2a8ff_max_snapshotsTb4b4b4:
Te6edf3keep Tff7b72= Tffa657maxTb4b4b4(T79c0ff1Tb4b4b4, Tff7b72selfTff7b72.Td2a8ff_max_snapshots Tff7b72- T79c0ff1Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ff_snapshots Tff7b72= Tb4b4b4[Tff7b72selfTff7b72.Td2a8ff_snapshotsTb4b4b4[T79c0ff0Tb4b4b4]Tb4b4b4, Tff7b72*Tff7b72selfTff7b72.Td2a8ff_snapshotsTb4b4b4[Tff7b72-Te6edf3keepTb4b4b4:Tb4b4b4]Tb4b4b4]
Tff7b72if Tffa657lenTb4b4b4(Tff7b72selfTff7b72.Td2a8ff_gc_statsTb4b4b4) Tff7b72> Tff7b72selfTff7b72.Td2a8ff_max_snapshotsTb4b4b4:
Te6edf3keep Tff7b72= Tffa657maxTb4b4b4(T79c0ff1Tb4b4b4, Tff7b72selfTff7b72.Td2a8ff_max_snapshots Tff7b72- T79c0ff1Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ff_gc_stats Tff7b72= Tb4b4b4[Tff7b72selfTff7b72.Td2a8ff_gc_statsTb4b4b4[T79c0ff0Tb4b4b4]Tb4b4b4, Tff7b72*Tff7b72selfTff7b72.Td2a8ff_gc_statsTb4b4b4[Tff7b72-Te6edf3keepTb4b4b4:Tb4b4b4]Tb4b4b4]
T8b949e# ------------------------------------------------------------------
T8b949e# Snapshots
T8b949e# ------------------------------------------------------------------
Tff7b72def Td2a8ffsnapshotTb4b4b4(Tff7b72selfTb4b4b4) Tff7b72-Tff7b72> Te6edf3tracemallocTff7b72.Td2a8ffSnapshot Tff7b72| Tff7b72NoneTb4b4b4:
Tff7b72if Tff7b72not Tff7b72selfTff7b72.Td2a8ffenabledTb4b4b4:
Tff7b72return Tff7b72None
Te6edf3snap Tff7b72= Te6edf3tracemallocTff7b72.Td2a8fftake_snapshotTb4b4b4(Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ff_snapshotsTff7b72.Td2a8ffappendTb4b4b4(Te6edf3snapTb4b4b4)
Tff7b72selfTff7b72.Td2a8ff_total_snapshots Tff7b72+Tff7b72= T79c0ff1
Tff7b72selfTff7b72.Td2a8ff_record_gc_statsTb4b4b4(Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ff_type_trackerTff7b72.Td2a8ffrecordTb4b4b4(Tb4b4b4)
Tff7b72selfTff7b72.Td2a8ff_trim_historyTb4b4b4(Tb4b4b4)
Tff7b72return Te6edf3snap
Tff7b72def Td2a8ffdiff_snapshotsTb4b4b4(
Tff7b72selfTb4b4b4,
Te6edf3new_idxTb4b4b4: Tffa657int Tff7b72= Tff7b72-T79c0ff1Tb4b4b4,
Te6edf3old_idxTb4b4b4: Tffa657int Tff7b72= T79c0ff0Tb4b4b4,
Te6edf3key_typeTb4b4b4: Tffa657str Tff7b72= Ta5d6ff"Ta5d6fflinenoTa5d6ff"Tb4b4b4,
Te6edf3top_nTb4b4b4: Tffa657int Tff7b72= T79c0ff40Tb4b4b4,
Tb4b4b4) Tff7b72-Tff7b72> Tffa657listTb4b4b4[Tffa657dictTb4b4b4[Tffa657strTb4b4b4, Te6edf3AnyTb4b4b4]Tb4b4b4]Tb4b4b4:
Tff7b72if Tff7b72not Tff7b72selfTff7b72.Td2a8ff_snapshots Tff7b72or Tffa657lenTb4b4b4(Tff7b72selfTff7b72.Td2a8ff_snapshotsTb4b4b4) Tff7b72< T79c0ff2Tb4b4b4:
Tff7b72return Tb4b4b4[Tb4b4b4]
Tff7b72if Te6edf3old_idx Tff7b72< T79c0ff0Tb4b4b4:
Te6edf3old_idx Tff7b72= Tffa657lenTb4b4b4(Tff7b72selfTff7b72.Td2a8ff_snapshotsTb4b4b4) Tff7b72+ Te6edf3old_idx
Tff7b72if Te6edf3new_idx Tff7b72< T79c0ff0Tb4b4b4:
Te6edf3new_idx Tff7b72= Tffa657lenTb4b4b4(Tff7b72selfTff7b72.Td2a8ff_snapshotsTb4b4b4) Tff7b72+ Te6edf3new_idx
Tff7b72if Te6edf3old_idx Tff7b72< T79c0ff0 Tff7b72or Te6edf3old_idx Tff7b72>Tff7b72= Tffa657lenTb4b4b4(Tff7b72selfTff7b72.Td2a8ff_snapshotsTb4b4b4)Tb4b4b4:
Tff7b72return Tb4b4b4[Tb4b4b4]
Tff7b72if Te6edf3new_idx Tff7b72< T79c0ff0 Tff7b72or Te6edf3new_idx Tff7b72>Tff7b72= Tffa657lenTb4b4b4(Tff7b72selfTff7b72.Td2a8ff_snapshotsTb4b4b4)Tb4b4b4:
Tff7b72return Tb4b4b4[Tb4b4b4]
Te6edf3diff Tff7b72= Tff7b72selfTff7b72.Td2a8ff_snapshotsTb4b4b4[Te6edf3new_idxTb4b4b4]Tff7b72.Td2a8ffcompare_toTb4b4b4(Tff7b72selfTff7b72.Td2a8ff_snapshotsTb4b4b4[Te6edf3old_idxTb4b4b4]Tb4b4b4, Te6edf3key_typeTb4b4b4)
Te6edf3resultTb4b4b4: Tffa657listTb4b4b4[Tffa657dictTb4b4b4[Tffa657strTb4b4b4, Te6edf3AnyTb4b4b4]Tb4b4b4] Tff7b72= Tb4b4b4[Tb4b4b4]
Tff7b72for Te6edf3stat Tff7b72in Te6edf3diffTb4b4b4[Tb4b4b4:Te6edf3top_nTb4b4b4]Tb4b4b4:
Te6edf3frame Tff7b72= Te6edf3statTff7b72.Td2a8fftracebackTb4b4b4[T79c0ff0Tb4b4b4]
Te6edf3resultTff7b72.Td2a8ffappendTb4b4b4(
Tb4b4b4{
Ta5d6ff"Ta5d6ffsizeTa5d6ff"Tb4b4b4: Te6edf3statTff7b72.Td2a8ffsizeTb4b4b4,
Ta5d6ff"Ta5d6ffsize_mibTa5d6ff"Tb4b4b4: Tffa657roundTb4b4b4(Te6edf3statTff7b72.Td2a8ffsize Tff7b72/ Tb4b4b4(T79c0ff1024 Tff7b72* T79c0ff1024Tb4b4b4)Tb4b4b4, T79c0ff3Tb4b4b4)Tb4b4b4,
Ta5d6ff"Ta5d6ffcountTa5d6ff"Tb4b4b4: Te6edf3statTff7b72.Td2a8ffcountTb4b4b4,
Ta5d6ff"Ta5d6fffileTa5d6ff"Tb4b4b4: Te6edf3frameTff7b72.Td2a8fffilenameTb4b4b4,
Ta5d6ff"Ta5d6fflineTa5d6ff"Tb4b4b4: Te6edf3frameTff7b72.Td2a8fflinenoTb4b4b4,
Tb4b4b4}Tb4b4b4,
Tb4b4b4)
Tff7b72return Te6edf3result
Tff7b72def Td2a8fftop_allocation_sitesTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3top_nTb4b4b4: Tffa657int Tff7b72= T79c0ff40Tb4b4b4) Tff7b72-Tff7b72> Tffa657listTb4b4b4[Tffa657dictTb4b4b4[Tffa657strTb4b4b4, Te6edf3AnyTb4b4b4]Tb4b4b4]Tb4b4b4:
Tff7b72if Tff7b72not Tff7b72selfTff7b72.Td2a8ffenabledTb4b4b4:
Tff7b72return Tb4b4b4[Tb4b4b4]
Te6edf3snap Tff7b72= Te6edf3tracemallocTff7b72.Td2a8fftake_snapshotTb4b4b4(Tb4b4b4)
Te6edf3stats Tff7b72= Te6edf3snapTff7b72.Td2a8ffstatisticsTb4b4b4(Ta5d6ff"Ta5d6fflinenoTa5d6ff"Tb4b4b4, Tff7b72TrueTb4b4b4)
Te6edf3resultTb4b4b4: Tffa657listTb4b4b4[Tffa657dictTb4b4b4[Tffa657strTb4b4b4, Te6edf3AnyTb4b4b4]Tb4b4b4] Tff7b72= Tb4b4b4[Tb4b4b4]
Tff7b72for Te6edf3stat Tff7b72in Te6edf3statsTb4b4b4[Tb4b4b4:Te6edf3top_nTb4b4b4]Tb4b4b4:
Te6edf3frame Tff7b72= Te6edf3statTff7b72.Td2a8fftracebackTb4b4b4[T79c0ff0Tb4b4b4]
Te6edf3resultTff7b72.Td2a8ffappendTb4b4b4(
Tb4b4b4{
Ta5d6ff"Ta5d6ffsizeTa5d6ff"Tb4b4b4: Te6edf3statTff7b72.Td2a8ffsizeTb4b4b4,
Ta5d6ff"Ta5d6ffsize_mibTa5d6ff"Tb4b4b4: Tffa657roundTb4b4b4(Te6edf3statTff7b72.Td2a8ffsize Tff7b72/ Tb4b4b4(T79c0ff1024 Tff7b72* T79c0ff1024Tb4b4b4)Tb4b4b4, T79c0ff3Tb4b4b4)Tb4b4b4,
Ta5d6ff"Ta5d6ffcountTa5d6ff"Tb4b4b4: Te6edf3statTff7b72.Td2a8ffcountTb4b4b4,
Ta5d6ff"Ta5d6fffileTa5d6ff"Tb4b4b4: Te6edf3frameTff7b72.Td2a8fffilenameTb4b4b4,
Ta5d6ff"Ta5d6fflineTa5d6ff"Tb4b4b4: Te6edf3frameTff7b72.Td2a8fflinenoTb4b4b4,
Tb4b4b4}Tb4b4b4,
Tb4b4b4)
Tff7b72return Te6edf3result
T8b949e# ------------------------------------------------------------------
T8b949e# GC generation tracking (critical for incremental GC diagnostics)
T8b949e# ------------------------------------------------------------------
Tff7b72def Td2a8ff_record_gc_statsTb4b4b4(Tff7b72selfTb4b4b4) Tff7b72-Tff7b72> Tff7b72NoneTb4b4b4:
Te6edf3g0 Tff7b72= Te6edf3g1 Tff7b72= Te6edf3g2 Tff7b72= Tff7b72-T79c0ff1
Tff7b72tryTb4b4b4:
Te6edf3g0 Tff7b72= Tffa657lenTb4b4b4(Te6edf3gcTff7b72.Td2a8ffget_objectsTb4b4b4(T79c0ff0Tb4b4b4)Tb4b4b4)
Te6edf3g1 Tff7b72= Tffa657lenTb4b4b4(Te6edf3gcTff7b72.Td2a8ffget_objectsTb4b4b4(T79c0ff1Tb4b4b4)Tb4b4b4)
Te6edf3g2 Tff7b72= Tffa657lenTb4b4b4(Te6edf3gcTff7b72.Td2a8ffget_objectsTb4b4b4(T79c0ff2Tb4b4b4)Tb4b4b4)
Tff7b72except Tf85149TypeErrorTb4b4b4:
Te6edf3g0 Tff7b72= Te6edf3g1 Tff7b72= Te6edf3g2 Tff7b72= Tff7b72-T79c0ff1
Tff7b72except Tf85149ExceptionTb4b4b4:
Tff7b72pass
Tff7b72selfTff7b72.Td2a8ff_gc_statsTff7b72.Td2a8ffappendTb4b4b4(
Tb4b4b4{
Ta5d6ff"Ta5d6ffgen0Ta5d6ff"Tb4b4b4: Te6edf3g0Tb4b4b4,
Ta5d6ff"Ta5d6ffgen1Ta5d6ff"Tb4b4b4: Te6edf3g1Tb4b4b4,
Ta5d6ff"Ta5d6ffgen2Ta5d6ff"Tb4b4b4: Te6edf3g2Tb4b4b4,
Ta5d6ff"Ta5d6fftotalTa5d6ff"Tb4b4b4: Tffa657sumTb4b4b4(Te6edf3x Tff7b72for Te6edf3x Tff7b72in Tb4b4b4(Te6edf3g0Tb4b4b4, Te6edf3g1Tb4b4b4, Te6edf3g2Tb4b4b4) Tff7b72if Te6edf3x Tff7b72>Tff7b72= T79c0ff0Tb4b4b4)Tb4b4b4,
Ta5d6ff"Ta5d6ffthresholdsTa5d6ff"Tb4b4b4: Tffa657listTb4b4b4(Te6edf3gcTff7b72.Td2a8ffget_thresholdTb4b4b4(Tb4b4b4)Tb4b4b4)Tb4b4b4,
Ta5d6ff"Ta5d6ffcountTa5d6ff"Tb4b4b4: Te6edf3gcTff7b72.Td2a8ffget_countTb4b4b4(Tb4b4b4)Tb4b4b4,
Ta5d6ff"Ta5d6fffrozenTa5d6ff"Tb4b4b4: Tffa657getattrTb4b4b4(Te6edf3gcTb4b4b4, Ta5d6ff"Ta5d6fffreeze_countTa5d6ff"Tb4b4b4, T79c0ff0Tb4b4b4)Tb4b4b4,
Tb4b4b4}Tb4b4b4,
Tb4b4b4)
Tff7b72def Td2a8ffgc_statsTb4b4b4(Tff7b72selfTb4b4b4) Tff7b72-Tff7b72> Tffa657dictTb4b4b4[Tffa657strTb4b4b4, Te6edf3AnyTb4b4b4]Tb4b4b4:
Tff7b72if Tff7b72not Tff7b72selfTff7b72.Td2a8ff_gc_statsTb4b4b4:
Tff7b72return Tb4b4b4{Ta5d6ff"Ta5d6ffavailableTa5d6ff"Tb4b4b4: Tff7b72FalseTb4b4b4}
Te6edf3first Tff7b72= Tff7b72selfTff7b72.Td2a8ff_gc_statsTb4b4b4[T79c0ff0Tb4b4b4]
Te6edf3last Tff7b72= Tff7b72selfTff7b72.Td2a8ff_gc_statsTb4b4b4[Tff7b72-T79c0ff1Tb4b4b4]
Tff7b72return Tb4b4b4{
Ta5d6ff"Ta5d6ffavailableTa5d6ff"Tb4b4b4: Tff7b72TrueTb4b4b4,
Ta5d6ff"Ta5d6ffsnapshots_takenTa5d6ff"Tb4b4b4: Tffa657lenTb4b4b4(Tff7b72selfTff7b72.Td2a8ff_snapshotsTb4b4b4)Tb4b4b4,
Ta5d6ff"Ta5d6ffrecordsTa5d6ff"Tb4b4b4: Tffa657lenTb4b4b4(Tff7b72selfTff7b72.Td2a8ff_gc_statsTb4b4b4)Tb4b4b4,
Ta5d6ff"Ta5d6fffirstTa5d6ff"Tb4b4b4: Te6edf3firstTb4b4b4,
Ta5d6ff"Ta5d6fflastTa5d6ff"Tb4b4b4: Te6edf3lastTb4b4b4,
Ta5d6ff"Ta5d6ffdeltasTa5d6ff"Tb4b4b4: Tb4b4b4{
Te6edf3kTb4b4b4: Te6edf3lastTff7b72.Td2a8ffgetTb4b4b4(Te6edf3kTb4b4b4, T79c0ff0Tb4b4b4) Tff7b72- Te6edf3firstTff7b72.Td2a8ffgetTb4b4b4(Te6edf3kTb4b4b4, T79c0ff0Tb4b4b4)
Tff7b72for Te6edf3k Tff7b72in Tb4b4b4(Ta5d6ff"Ta5d6ffgen0Ta5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ffgen1Ta5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ffgen2Ta5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6fftotalTa5d6ff"Tb4b4b4)
Tff7b72if Te6edf3k Tff7b72in Te6edf3first Tff7b72and Te6edf3k Tff7b72in Te6edf3last
Tb4b4b4}Tb4b4b4,
Ta5d6ff"Ta5d6ffhistoryTa5d6ff"Tb4b4b4: Tff7b72selfTff7b72.Td2a8ff_gc_statsTb4b4b4,
Tb4b4b4}
T8b949e# ------------------------------------------------------------------
T8b949e# Heap analysis (gc.get_objects based)
T8b949e# ------------------------------------------------------------------
Tff7b72def Td2a8ffheap_by_typeTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3top_nTb4b4b4: Tffa657int Tff7b72= T79c0ff40Tb4b4b4) Tff7b72-Tff7b72> Tffa657listTb4b4b4[Tffa657dictTb4b4b4[Tffa657strTb4b4b4, Te6edf3AnyTb4b4b4]Tb4b4b4]Tb4b4b4:
T8b949e"""Count live objects grouped by their type name."""
Te6edf3countsTb4b4b4: Tffa657dictTb4b4b4[Tffa657strTb4b4b4, Tffa657intTb4b4b4] Tff7b72= Tb4b4b4{Tb4b4b4}
Te6edf3sizesTb4b4b4: Tffa657dictTb4b4b4[Tffa657strTb4b4b4, Tffa657intTb4b4b4] Tff7b72= Tb4b4b4{Tb4b4b4}
Tff7b72tryTb4b4b4:
Tff7b72for Te6edf3obj Tff7b72in Te6edf3gcTff7b72.Td2a8ffget_objectsTb4b4b4(Tb4b4b4)Tb4b4b4:
Tff7b72tryTb4b4b4:
Te6edf3tname Tff7b72= Te6edf3_safe_type_nameTb4b4b4(Te6edf3objTb4b4b4)
Te6edf3countsTb4b4b4[Te6edf3tnameTb4b4b4] Tff7b72= Te6edf3countsTff7b72.Td2a8ffgetTb4b4b4(Te6edf3tnameTb4b4b4, T79c0ff0Tb4b4b4) Tff7b72+ T79c0ff1
Te6edf3sizesTb4b4b4[Te6edf3tnameTb4b4b4] Tff7b72= Te6edf3sizesTff7b72.Td2a8ffgetTb4b4b4(Te6edf3tnameTb4b4b4, T79c0ff0Tb4b4b4) Tff7b72+ Te6edf3_obj_sizeTb4b4b4(Te6edf3objTb4b4b4)
Tff7b72except Tf85149ExceptionTb4b4b4:
Tff7b72continue
Tff7b72except Tf85149ExceptionTb4b4b4:
Tff7b72return Tb4b4b4[Tb4b4b4]
Te6edf3sorted_types Tff7b72= Tffa657sortedTb4b4b4(Te6edf3countsTff7b72.Td2a8ffitemsTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3keyTff7b72=Tff7b72lambda Te6edf3xTb4b4b4: Tff7b72-Te6edf3xTb4b4b4[T79c0ff1Tb4b4b4]Tb4b4b4)
Tff7b72return Tb4b4b4[
Tb4b4b4{
Ta5d6ff"Ta5d6fftypeTa5d6ff"Tb4b4b4: Te6edf3tnameTb4b4b4,
Ta5d6ff"Ta5d6ffcountTa5d6ff"Tb4b4b4: Te6edf3cntTb4b4b4,
Ta5d6ff"Ta5d6ffsize_bytesTa5d6ff"Tb4b4b4: Te6edf3sizesTff7b72.Td2a8ffgetTb4b4b4(Te6edf3tnameTb4b4b4, T79c0ff0Tb4b4b4)Tb4b4b4,
Ta5d6ff"Ta5d6ffsize_mibTa5d6ff"Tb4b4b4: Tffa657roundTb4b4b4(Te6edf3sizesTff7b72.Td2a8ffgetTb4b4b4(Te6edf3tnameTb4b4b4, T79c0ff0Tb4b4b4) Tff7b72/ Tb4b4b4(T79c0ff1024 Tff7b72* T79c0ff1024Tb4b4b4)Tb4b4b4, T79c0ff3Tb4b4b4)Tb4b4b4,
Tb4b4b4}
Tff7b72for Te6edf3tnameTb4b4b4, Te6edf3cnt Tff7b72in Te6edf3sorted_typesTb4b4b4[Tb4b4b4:Te6edf3top_nTb4b4b4]
Tb4b4b4]
Tff7b72def Td2a8ffheap_by_categoryTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3top_nTb4b4b4: Tffa657int Tff7b72= T79c0ff40Tb4b4b4) Tff7b72-Tff7b72> Tffa657listTb4b4b4[Tffa657dictTb4b4b4[Tffa657strTb4b4b4, Te6edf3AnyTb4b4b4]Tb4b4b4]Tb4b4b4:
T8b949e"""Count live objects grouped by category (RNS, LXMF, meshchatx, etc)."""
Te6edf3countsTb4b4b4: Tffa657dictTb4b4b4[Tffa657strTb4b4b4, Tffa657intTb4b4b4] Tff7b72= Tb4b4b4{Tb4b4b4}
Te6edf3sizesTb4b4b4: Tffa657dictTb4b4b4[Tffa657strTb4b4b4, Tffa657intTb4b4b4] Tff7b72= Tb4b4b4{Tb4b4b4}
Tff7b72tryTb4b4b4:
Tff7b72for Te6edf3obj Tff7b72in Te6edf3gcTff7b72.Td2a8ffget_objectsTb4b4b4(Tb4b4b4)Tb4b4b4:
Tff7b72tryTb4b4b4:
Te6edf3cat Tff7b72= Te6edf3_classifyTb4b4b4(Te6edf3objTb4b4b4)
Te6edf3countsTb4b4b4[Te6edf3catTb4b4b4] Tff7b72= Te6edf3countsTff7b72.Td2a8ffgetTb4b4b4(Te6edf3catTb4b4b4, T79c0ff0Tb4b4b4) Tff7b72+ T79c0ff1
Te6edf3sizesTb4b4b4[Te6edf3catTb4b4b4] Tff7b72= Te6edf3sizesTff7b72.Td2a8ffgetTb4b4b4(Te6edf3catTb4b4b4, T79c0ff0Tb4b4b4) Tff7b72+ Te6edf3_obj_sizeTb4b4b4(Te6edf3objTb4b4b4)
Tff7b72except Tf85149ExceptionTb4b4b4:
Tff7b72continue
Tff7b72except Tf85149ExceptionTb4b4b4:
Tff7b72return Tb4b4b4[Tb4b4b4]
Te6edf3sorted_cats Tff7b72= Tffa657sortedTb4b4b4(Te6edf3countsTff7b72.Td2a8ffitemsTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3keyTff7b72=Tff7b72lambda Te6edf3xTb4b4b4: Tff7b72-Te6edf3xTb4b4b4[T79c0ff1Tb4b4b4]Tb4b4b4)
Tff7b72return Tb4b4b4[
Tb4b4b4{
Ta5d6ff"Ta5d6ffcategoryTa5d6ff"Tb4b4b4: Te6edf3catTb4b4b4,
Ta5d6ff"Ta5d6ffcountTa5d6ff"Tb4b4b4: Te6edf3cntTb4b4b4,
Ta5d6ff"Ta5d6ffsize_bytesTa5d6ff"Tb4b4b4: Te6edf3sizesTff7b72.Td2a8ffgetTb4b4b4(Te6edf3catTb4b4b4, T79c0ff0Tb4b4b4)Tb4b4b4,
Ta5d6ff"Ta5d6ffsize_mibTa5d6ff"Tb4b4b4: Tffa657roundTb4b4b4(Te6edf3sizesTff7b72.Td2a8ffgetTb4b4b4(Te6edf3catTb4b4b4, T79c0ff0Tb4b4b4) Tff7b72/ Tb4b4b4(T79c0ff1024 Tff7b72* T79c0ff1024Tb4b4b4)Tb4b4b4, T79c0ff3Tb4b4b4)Tb4b4b4,
Tb4b4b4}
Tff7b72for Te6edf3catTb4b4b4, Te6edf3cnt Tff7b72in Te6edf3sorted_catsTb4b4b4[Tb4b4b4:Te6edf3top_nTb4b4b4]
Tb4b4b4]
Tff7b72def Td2a8ffaccumulating_typesTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3top_nTb4b4b4: Tffa657int Tff7b72= T79c0ff20Tb4b4b4) Tff7b72-Tff7b72> Tffa657listTb4b4b4[Tffa657tupleTb4b4b4[Tffa657strTb4b4b4, Tffa657intTb4b4b4]Tb4b4b4]Tb4b4b4:
Tff7b72return Tff7b72selfTff7b72.Td2a8ff_type_trackerTff7b72.Td2a8ffaccumulating_typesTb4b4b4[Tb4b4b4:Te6edf3top_nTb4b4b4]
Tff7b72def Td2a8fftype_growth_since_startTb4b4b4(Tff7b72selfTb4b4b4, Te6edf3top_nTb4b4b4: Tffa657int Tff7b72= T79c0ff20Tb4b4b4) Tff7b72-Tff7b72> Tffa657listTb4b4b4[Tffa657tupleTb4b4b4[Tffa657strTb4b4b4, Tffa657intTb4b4b4]Tb4b4b4]Tb4b4b4:
Tff7b72return Tff7b72selfTff7b72.Td2a8ff_type_trackerTff7b72.Td2a8ffgrowth_since_firstTb4b4b4[Tb4b4b4:Te6edf3top_nTb4b4b4]
T8b949e# ------------------------------------------------------------------
T8b949e# Reference cycle detection helpers
T8b949e# ------------------------------------------------------------------
Tff7b72def Td2a8fffind_referrersTb4b4b4(
Tff7b72selfTb4b4b4,
Te6edf3type_nameTb4b4b4: Tffa657strTb4b4b4,
Te6edf3max_resultsTb4b4b4: Tffa657int Tff7b72= T79c0ff20Tb4b4b4,
Tb4b4b4) Tff7b72-Tff7b72> Tffa657listTb4b4b4[Tffa657dictTb4b4b4[Tffa657strTb4b4b4, Te6edf3AnyTb4b4b4]Tb4b4b4]Tb4b4b4:
T8b949e"""Find referrers of objects of a given type. Useful to trace who holds references."""
Te6edf3matchesTb4b4b4: Tffa657listTb4b4b4[Te6edf3AnyTb4b4b4] Tff7b72= Tb4b4b4[Tb4b4b4]
Tff7b72tryTb4b4b4:
Tff7b72for Te6edf3obj Tff7b72in Te6edf3gcTff7b72.Td2a8ffget_objectsTb4b4b4(Tb4b4b4)Tb4b4b4:
Tff7b72tryTb4b4b4:
Tff7b72if Te6edf3_safe_type_nameTb4b4b4(Te6edf3objTb4b4b4) Tff7b72== Te6edf3type_nameTb4b4b4:
Te6edf3matchesTff7b72.Td2a8ffappendTb4b4b4(Te6edf3objTb4b4b4)
Tff7b72if Tffa657lenTb4b4b4(Te6edf3matchesTb4b4b4) Tff7b72>Tff7b72= Te6edf3max_resultsTb4b4b4:
Tff7b72break
Tff7b72except Tf85149ExceptionTb4b4b4:
Tff7b72continue
Tff7b72except Tf85149ExceptionTb4b4b4:
Tff7b72return Tb4b4b4[Tb4b4b4]
Te6edf3resultTb4b4b4: Tffa657listTb4b4b4[Tffa657dictTb4b4b4[Tffa657strTb4b4b4, Te6edf3AnyTb4b4b4]Tb4b4b4] Tff7b72= Tb4b4b4[Tb4b4b4]
Tff7b72for Te6edf3obj Tff7b72in Te6edf3matchesTb4b4b4:
Te6edf3refsTb4b4b4: Tffa657listTb4b4b4[Tffa657strTb4b4b4] Tff7b72= Tb4b4b4[Tb4b4b4]
Tff7b72tryTb4b4b4:
Tff7b72for Te6edf3ref Tff7b72in Te6edf3gcTff7b72.Td2a8ffget_referrersTb4b4b4(Te6edf3objTb4b4b4)Tb4b4b4:
Tff7b72tryTb4b4b4:
Te6edf3refsTff7b72.Td2a8ffappendTb4b4b4(Ta5d6fffTa5d6ff"Tffd700{Te6edf3_safe_type_nameTb4b4b4(Te6edf3refTb4b4b4)Tffd700}Ta5d6ff at Tffd700{Tffa657idTb4b4b4(Te6edf3refTb4b4b4)Tffd700:Ta5d6ff#xTffd700}Ta5d6ff"Tb4b4b4)
Tff7b72except Tf85149ExceptionTb4b4b4:
Te6edf3refsTff7b72.Td2a8ffappendTb4b4b4(Ta5d6ff"Ta5d6ff<error>Ta5d6ff"Tb4b4b4)
Tff7b72if Tffa657lenTb4b4b4(Te6edf3refsTb4b4b4) Tff7b72>Tff7b72= T79c0ff10Tb4b4b4:
Tff7b72break
Tff7b72except Tf85149ExceptionTb4b4b4:
Te6edf3refs Tff7b72= Tb4b4b4[Ta5d6ff"Ta5d6ff<error>Ta5d6ff"Tb4b4b4]
Te6edf3resultTff7b72.Td2a8ffappendTb4b4b4(
Tb4b4b4{
Ta5d6ff"Ta5d6fftypeTa5d6ff"Tb4b4b4: Te6edf3_safe_type_nameTb4b4b4(Te6edf3objTb4b4b4)Tb4b4b4,
Ta5d6ff"Ta5d6ffidTa5d6ff"Tb4b4b4: Tffa657idTb4b4b4(Te6edf3objTb4b4b4)Tb4b4b4,
Ta5d6ff"Ta5d6ffsizeTa5d6ff"Tb4b4b4: Te6edf3_obj_sizeTb4b4b4(Te6edf3objTb4b4b4)Tb4b4b4,
Ta5d6ff"Ta5d6ffreferrersTa5d6ff"Tb4b4b4: Te6edf3refsTb4b4b4,
Tb4b4b4}Tb4b4b4,
Tb4b4b4)
Tff7b72return Te6edf3result
Tff7b72def Td2a8fffind_cyclic_garbageTb4b4b4(Tff7b72selfTb4b4b4) Tff7b72-Tff7b72> Tffa657listTb4b4b4[Tffa657dictTb4b4b4[Tffa657strTb4b4b4, Te6edf3AnyTb4b4b4]Tb4b4b4]Tb4b4b4:
T8b949e"""Run gc.collect() and return info about what was collected."""
Te6edf3unreachable_before Tff7b72= Te6edf3gcTff7b72.Td2a8ffget_countTb4b4b4(Tb4b4b4)
Te6edf3colsTb4b4b4: Tffa657listTb4b4b4[Tffa657intTb4b4b4] Tff7b72= Tb4b4b4[Tb4b4b4]
Tff7b72for Te6edf3gen Tff7b72in Tffa657rangeTb4b4b4(T79c0ff3Tb4b4b4)Tb4b4b4:
Tff7b72tryTb4b4b4:
Te6edf3n Tff7b72= Te6edf3gcTff7b72.Td2a8ffcollectTb4b4b4(Te6edf3genTb4b4b4)
Te6edf3colsTff7b72.Td2a8ffappendTb4b4b4(Te6edf3nTb4b4b4)
Tff7b72except Tf85149ExceptionTb4b4b4:
Te6edf3colsTff7b72.Td2a8ffappendTb4b4b4(Tff7b72-T79c0ff1Tb4b4b4)
Te6edf3unreachable_after Tff7b72= Te6edf3gcTff7b72.Td2a8ffget_countTb4b4b4(Tb4b4b4)
Tff7b72return Tb4b4b4[
Tb4b4b4{
Ta5d6ff"Ta5d6ffgenerationTa5d6ff"Tb4b4b4: Te6edf3iTb4b4b4,
Ta5d6ff"Ta5d6ffcollectedTa5d6ff"Tb4b4b4: Te6edf3nTb4b4b4,
Tb4b4b4}
Tff7b72for Te6edf3iTb4b4b4, Te6edf3n Tff7b72in Tffa657enumerateTb4b4b4(Te6edf3colsTb4b4b4)
Tb4b4b4] Tff7b72+ Tb4b4b4[
Tb4b4b4{
Ta5d6ff"Ta5d6ffunreachable_beforeTa5d6ff"Tb4b4b4: Tffa657listTb4b4b4(Te6edf3unreachable_beforeTb4b4b4)Tb4b4b4,
Ta5d6ff"Ta5d6ffunreachable_afterTa5d6ff"Tb4b4b4: Tffa657listTb4b4b4(Te6edf3unreachable_afterTb4b4b4)Tb4b4b4,
Tb4b4b4}Tb4b4b4,
Tb4b4b4]
Tff7b72def Td2a8ffgc_garbage_typesTb4b4b4(Tff7b72selfTb4b4b4) Tff7b72-Tff7b72> Tffa657listTb4b4b4[Tffa657dictTb4b4b4[Tffa657strTb4b4b4, Tffa657str Tff7b72| Tffa657intTb4b4b4]Tb4b4b4]Tb4b4b4:
T8b949e"""Show types of objects in gc.garbage (uncollectable objects)."""
Te6edf3countsTb4b4b4: Tffa657dictTb4b4b4[Tffa657strTb4b4b4, Tffa657intTb4b4b4] Tff7b72= Tb4b4b4{Tb4b4b4}
Tff7b72tryTb4b4b4:
Tff7b72for Te6edf3obj Tff7b72in Te6edf3gcTff7b72.Td2a8ffgarbageTb4b4b4:
Tff7b72tryTb4b4b4:
Te6edf3tname Tff7b72= Te6edf3_safe_type_nameTb4b4b4(Te6edf3objTb4b4b4)
Te6edf3countsTb4b4b4[Te6edf3tnameTb4b4b4] Tff7b72= Te6edf3countsTff7b72.Td2a8ffgetTb4b4b4(Te6edf3tnameTb4b4b4, T79c0ff0Tb4b4b4) Tff7b72+ T79c0ff1
Tff7b72except Tf85149ExceptionTb4b4b4:
Tff7b72continue
Tff7b72except Tf85149ExceptionTb4b4b4:
Tff7b72pass
Te6edf3sorted_counts Tff7b72= Tffa657sortedTb4b4b4(Te6edf3countsTff7b72.Td2a8ffitemsTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3keyTff7b72=Tff7b72lambda Te6edf3xTb4b4b4: Tff7b72-Te6edf3xTb4b4b4[T79c0ff1Tb4b4b4]Tb4b4b4)
Tff7b72return Tb4b4b4[Tb4b4b4{Ta5d6ff"Ta5d6fftypeTa5d6ff"Tb4b4b4: Te6edf3tTb4b4b4, Ta5d6ff"Ta5d6ffcountTa5d6ff"Tb4b4b4: Te6edf3cTb4b4b4} Tff7b72for Te6edf3tTb4b4b4, Te6edf3c Tff7b72in Te6edf3sorted_countsTb4b4b4]
T8b949e# ------------------------------------------------------------------
T8b949e# Consolidated report
T8b949e# ------------------------------------------------------------------
Tff7b72def Td2a8ffreportTb4b4b4(Tff7b72selfTb4b4b4) Tff7b72-Tff7b72> Tffa657dictTb4b4b4[Tffa657strTb4b4b4, Te6edf3AnyTb4b4b4]Tb4b4b4:
T8b949e"""Generate a comprehensive memory diagnostics report."""
Tff7b72if Tff7b72not Tff7b72selfTff7b72.Td2a8ff_enabledTb4b4b4:
Tff7b72return Tb4b4b4{
Ta5d6ff"Ta5d6ffenabledTa5d6ff"Tb4b4b4: Tff7b72FalseTb4b4b4,
Ta5d6ff"Ta5d6ffmessageTa5d6ff"Tb4b4b4: Ta5d6ff"Ta5d6ffMemory diagnostics not enabled (pass --memory-diag)Ta5d6ff"Tb4b4b4,
Tb4b4b4}
Te6edf3current_tracedTb4b4b4, Te6edf3peak_traced Tff7b72= Tb4b4b4(T79c0ff0Tb4b4b4, T79c0ff0Tb4b4b4)
Tff7b72if Te6edf3tracemallocTff7b72.Td2a8ffis_tracingTb4b4b4(Tb4b4b4)Tb4b4b4:
Te6edf3current_tracedTb4b4b4, Te6edf3peak_traced Tff7b72= Te6edf3tracemallocTff7b72.Td2a8ffget_traced_memoryTb4b4b4(Tb4b4b4)
Te6edf3growth Tff7b72= Tff7b72selfTff7b72.Td2a8ffdiff_snapshotsTb4b4b4(Te6edf3top_nTff7b72=T79c0ff30Tb4b4b4)
Te6edf3top_sites Tff7b72= Tff7b72selfTff7b72.Td2a8fftop_allocation_sitesTb4b4b4(Te6edf3top_nTff7b72=T79c0ff15Tb4b4b4)
Te6edf3gc_info Tff7b72= Tff7b72selfTff7b72.Td2a8ffgc_statsTb4b4b4(Tb4b4b4)
Te6edf3top_types Tff7b72= Tff7b72selfTff7b72.Td2a8ffheap_by_typeTb4b4b4(Te6edf3top_nTff7b72=T79c0ff30Tb4b4b4)
Te6edf3cat_types Tff7b72= Tff7b72selfTff7b72.Td2a8ffheap_by_categoryTb4b4b4(Tb4b4b4)
Te6edf3accumulating Tff7b72= Tff7b72selfTff7b72.Td2a8ffaccumulating_typesTb4b4b4(Tb4b4b4)
Te6edf3growth_types Tff7b72= Tff7b72selfTff7b72.Td2a8fftype_growth_since_startTb4b4b4(Tb4b4b4)
Tff7b72return Tb4b4b4{
Ta5d6ff"Ta5d6ffenabledTa5d6ff"Tb4b4b4: Tff7b72TrueTb4b4b4,
Ta5d6ff"Ta5d6ffpython_versionTa5d6ff"Tb4b4b4: Te6edf3sysTff7b72.Td2a8ffversionTb4b4b4,
Ta5d6ff"Ta5d6ffincremental_gcTa5d6ff"Tb4b4b4: Tff7b72selfTff7b72.Td2a8ff_detect_incremental_gcTb4b4b4(Tb4b4b4)Tb4b4b4,
Ta5d6ff"Ta5d6fftracemallocTa5d6ff"Tb4b4b4: Tb4b4b4{
Ta5d6ff"Ta5d6ffcurrent_bytesTa5d6ff"Tb4b4b4: Te6edf3current_tracedTb4b4b4,
Ta5d6ff"Ta5d6ffcurrent_mibTa5d6ff"Tb4b4b4: Tffa657roundTb4b4b4(Te6edf3current_traced Tff7b72/ Tb4b4b4(T79c0ff1024 Tff7b72* T79c0ff1024Tb4b4b4)Tb4b4b4, T79c0ff3Tb4b4b4)Tb4b4b4,
Ta5d6ff"Ta5d6ffpeak_bytesTa5d6ff"Tb4b4b4: Te6edf3peak_tracedTb4b4b4,
Ta5d6ff"Ta5d6ffpeak_mibTa5d6ff"Tb4b4b4: Tffa657roundTb4b4b4(Te6edf3peak_traced Tff7b72/ Tb4b4b4(T79c0ff1024 Tff7b72* T79c0ff1024Tb4b4b4)Tb4b4b4, T79c0ff3Tb4b4b4)Tb4b4b4,
Tb4b4b4}Tb4b4b4,
Ta5d6ff"Ta5d6ffgcTa5d6ff"Tb4b4b4: Te6edf3gc_infoTb4b4b4,
Ta5d6ff"Ta5d6ffgrowth_vs_baselineTa5d6ff"Tb4b4b4: Te6edf3growthTb4b4b4,
Ta5d6ff"Ta5d6fftop_allocation_sitesTa5d6ff"Tb4b4b4: Te6edf3top_sitesTb4b4b4,
Ta5d6ff"Ta5d6ffheap_by_typeTa5d6ff"Tb4b4b4: Te6edf3top_typesTb4b4b4,
Ta5d6ff"Ta5d6ffheap_by_categoryTa5d6ff"Tb4b4b4: Te6edf3cat_typesTb4b4b4,
Ta5d6ff"Ta5d6ffaccumulating_typesTa5d6ff"Tb4b4b4: Tb4b4b4[Tb4b4b4{Ta5d6ff"Ta5d6fftypeTa5d6ff"Tb4b4b4: Te6edf3tTb4b4b4, Ta5d6ff"Ta5d6ffgrowthTa5d6ff"Tb4b4b4: Te6edf3cTb4b4b4} Tff7b72for Te6edf3tTb4b4b4, Te6edf3c Tff7b72in Te6edf3accumulatingTb4b4b4]Tb4b4b4,
Ta5d6ff"Ta5d6fftype_growth_since_startTa5d6ff"Tb4b4b4: Tb4b4b4[
Tb4b4b4{Ta5d6ff"Ta5d6fftypeTa5d6ff"Tb4b4b4: Te6edf3tTb4b4b4, Ta5d6ff"Ta5d6ffgrowthTa5d6ff"Tb4b4b4: Te6edf3cTb4b4b4} Tff7b72for Te6edf3tTb4b4b4, Te6edf3c Tff7b72in Te6edf3growth_types
Tb4b4b4]Tb4b4b4,
Ta5d6ff"Ta5d6ffgc_freeze_countTa5d6ff"Tb4b4b4: Tffa657getattrTb4b4b4(Te6edf3gcTb4b4b4, Ta5d6ff"Ta5d6fffreeze_countTa5d6ff"Tb4b4b4, T79c0ff0Tb4b4b4)Tb4b4b4,
Ta5d6ff"Ta5d6ffsnapshot_countTa5d6ff"Tb4b4b4: Tffa657lenTb4b4b4(Tff7b72selfTff7b72.Td2a8ff_snapshotsTb4b4b4)Tb4b4b4,
Ta5d6ff"Ta5d6fftotal_snapshotsTa5d6ff"Tb4b4b4: Tff7b72selfTff7b72.Td2a8ff_total_snapshotsTb4b4b4,
Tb4b4b4}
Tf0883e@staticmethod
Tff7b72def Td2a8ff_detect_incremental_gcTb4b4b4(Tb4b4b4) Tff7b72-Tff7b72> Tffa657dictTb4b4b4[Tffa657strTb4b4b4, Te6edf3AnyTb4b4b4]Tb4b4b4:
T8b949e"""Detect if we're running on Python 3.14+ with incremental GC."""
Te6edf3version_info Tff7b72= Te6edf3sysTff7b72.Td2a8ffversion_info
Te6edf3resultTb4b4b4: Tffa657dictTb4b4b4[Tffa657strTb4b4b4, Te6edf3AnyTb4b4b4] Tff7b72= Tb4b4b4{
Ta5d6ff"Ta5d6ffis_incremental_gcTa5d6ff"Tb4b4b4: Te6edf3version_info Tff7b72>Tff7b72= Tb4b4b4(T79c0ff3Tb4b4b4, T79c0ff14Tb4b4b4)Tb4b4b4,
Ta5d6ff"Ta5d6ffpython_versionTa5d6ff"Tb4b4b4: Ta5d6fffTa5d6ff"Tffd700{Te6edf3version_infoTff7b72.Td2a8ffmajorTffd700}Ta5d6ff.Tffd700{Te6edf3version_infoTff7b72.Td2a8ffminorTffd700}Ta5d6ff.Tffd700{Te6edf3version_infoTff7b72.Td2a8ffmicroTffd700}Ta5d6ff"Tb4b4b4,
Tb4b4b4}
Tff7b72if Te6edf3version_info Tff7b72>Tff7b72= Tb4b4b4(T79c0ff3Tb4b4b4, T79c0ff14Tb4b4b4)Tb4b4b4:
Te6edf3thresh Tff7b72= Te6edf3gcTff7b72.Td2a8ffget_thresholdTb4b4b4(Tb4b4b4)
Te6edf3resultTb4b4b4[Ta5d6ff"Ta5d6ffthresholdsTa5d6ff"Tb4b4b4] Tff7b72= Tffa657listTb4b4b4(Te6edf3threshTb4b4b4)
Te6edf3resultTb4b4b4[Ta5d6ff"Ta5d6ffnoteTa5d6ff"Tb4b4b4] Tff7b72= Tb4b4b4(
Ta5d6ff"Ta5d6ffPython 3.14+ uses incremental GC. Ta5d6ff"
Ta5d6ff"Ta5d6ffFull collections may be deferred, causing cyclic garbage Ta5d6ff"
Ta5d6ff"Ta5d6ffto linger. Check Ta5d6ff'Ta5d6ffgc.deltas.gen2Ta5d6ff'Ta5d6ff growth.Ta5d6ff"
Tb4b4b4)
Tff7b72return Te6edf3result
T8b949e# ------------------------------------------------------------------
T8b949e# Module-level convenience
T8b949e# ------------------------------------------------------------------
Te6edf3_diagTb4b4b4: Te6edf3MemoryDiagnostics Tff7b72| Tff7b72None Tff7b72= Tff7b72None
Tff7b72def Td2a8ffget_diagnosticsTb4b4b4(Tb4b4b4) Tff7b72-Tff7b72> Te6edf3MemoryDiagnosticsTb4b4b4:
Tff7b72global Te6edf3_diag
Tff7b72if Te6edf3_diag Tff7b72is Tff7b72NoneTb4b4b4:
Te6edf3_diag Tff7b72= Te6edf3MemoryDiagnosticsTb4b4b4(Tb4b4b4)
Tff7b72return Te6edf3_diag
Tff7b72def Td2a8fftake_heap_snapshotTb4b4b4(Te6edf3include_tracemallocTb4b4b4: Tffa657bool Tff7b72= Tff7b72TrueTb4b4b4) Tff7b72-Tff7b72> Tffa657dictTb4b4b4[Tffa657strTb4b4b4, Te6edf3AnyTb4b4b4]Tb4b4b4:
T8b949e"""Convenience function: take a one-shot heap snapshot.
Useful for pdb / breakpoint() sessions::
from meshchatx.src.backend.diagnostics import take_heap_snapshot
report = take_heap_snapshot()
"""
Te6edf3diag Tff7b72= Te6edf3get_diagnosticsTb4b4b4(Tb4b4b4)
Te6edf3was_enabled Tff7b72= Te6edf3diagTff7b72.Td2a8ffenabled
Tff7b72if Tff7b72not Te6edf3was_enabled Tff7b72and Te6edf3include_tracemallocTb4b4b4:
Te6edf3diagTff7b72.Td2a8ffstartTb4b4b4(Tb4b4b4)
Te6edf3diagTff7b72.Td2a8ffsnapshotTb4b4b4(Tb4b4b4)
Te6edf3report Tff7b72= Te6edf3diagTff7b72.Td2a8ffreportTb4b4b4(Tb4b4b4)
Tff7b72if Tff7b72not Te6edf3was_enabled Tff7b72and Te6edf3include_tracemallocTb4b4b4:
Te6edf3diagTff7b72.Td2a8ffstopTb4b4b4(Tb4b4b4)
Tff7b72return Te6edf3report
──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────